package rpc;

import java.util.*;
import net.hangar5.xmlrpc.*;
import java.awt.event.*;
import java.io.*;

public class I2cRpcClient implements Serializable
{
   private final RpcClient client;
   private String superviseurUrl;
   private Vector trameMemory = new Vector();
   private transient Vector actionListeners;
   private transient Vector rpcExceptionListeners;
   private String error;

   public I2cRpcClient()
   {
      client = new RpcClient();
      client.setKeepAlive(false);
   }

   // Definir URL du client
   public boolean setUrl(String url)
   {
      boolean result = true;
      try
      {
	 client.setUrl(url);
	 superviseurUrl = url;
      }
      catch (Exception other)
      {
	 superviseurUrl = null;
	 result = false;
	 System.err.println ("Exception in client: "+other);
	 other.printStackTrace();
      }
      return result;
   }

   public String getUrl()
   {
      if (superviseurUrl != null)
      {
	 return superviseurUrl;
      }
      else return "url non initialisee";
   }


   public void doTrame(byte[] trame)
   {
      boolean resultat = false;
      final String methode = "doTrame";
      try
      {
	   Vector v = new Vector();
	   v.addElement(trame);
	   byte[] result = (byte[])client.execute(methode, v);
	   int l = result.length;
	   resultat = (trame.length == l);
	   if (resultat)
	   {
	      trameMemory.clear();
	      for (int i= 0; i < l; i++)
	      {
		  trameMemory.add(new Byte(result[i]));
		  trame[i] = result[i];
	      }
	      doTrameReceiveEvent();
	   }
     }
     catch (Exception x) {printError(x, methode);}   //printErreur(x, methode);}
   }

   private final void printError(final Exception x, final String methode)
   {
       String erreur = ("Execution de la méthode: " + methode +
	" impossible sur la borne dont l'url est: " + getUrl() + "  [" + x.toString() + "]");
	System.err.println(erreur);
	error = erreur;
	doRpcException(erreur);
   }

   public String getError()
   {
       return error;
   }

   public byte[] getReceivedTrame()
   {
     int l = trameMemory.size();
     byte[] result = new byte[l];
     for (int i = 0; i < trameMemory.size(); i++)
     {
	result[i] = ((Byte)trameMemory.get(i)).byteValue();
     }
     return result;
   }

   private void doTrameReceiveEvent()
   {
      ActionEvent actionEvt = new ActionEvent(this, 0, "trameI2c");
      fireActionPerformed(actionEvt);
   }

   public synchronized void removeActionListener(ActionListener l)
   {
      if (actionListeners != null && actionListeners.contains(l))
      {
	 Vector v = (Vector) actionListeners.clone();
	 v.removeElement(l);
	 actionListeners = v;
      }
   }

   public synchronized void addActionListener(ActionListener l)
   {
       Vector v = actionListeners == null ? new Vector(2) : (Vector) actionListeners.clone();
       if (!v.contains(l))
       {
	  v.addElement(l);
	  actionListeners = v;
       }
   }

   protected void fireActionPerformed(ActionEvent e)
   {
       if (actionListeners != null)
       {
	  Vector listeners = actionListeners;
	  int count = listeners.size();
	  for (int i = 0; i < count; i++)
	  {
	     ((ActionListener) listeners.elementAt(i)).actionPerformed(e);
	  }
       }
   }

   private void doRpcException(String message)
   {
      ExceptionEvent actionEvt = new ExceptionEvent(this, 0, message);
      fireRpcExceptionPerformed(actionEvt);
   }

   public synchronized void removeRpcExceptionListener(RpcExceptionListener l)
   {
      if (rpcExceptionListeners != null && rpcExceptionListeners.contains(l))
      {
	 Vector v = (Vector) rpcExceptionListeners.clone();
	 v.removeElement(l);
	 rpcExceptionListeners = v;
      }
   }

   public synchronized void addRpcExceptionListener(RpcExceptionListener l)
   {
       Vector v = rpcExceptionListeners == null ? new Vector(2) : (Vector) rpcExceptionListeners.clone();
       if (!v.contains(l))
       {
	  v.addElement(l);
	  rpcExceptionListeners = v;
       }
   }

   protected void fireRpcExceptionPerformed(ExceptionEvent e)
   {
       if (rpcExceptionListeners != null)
       {
	  Vector listeners = rpcExceptionListeners;
	  int count = listeners.size();
	  for (int i = 0; i < count; i++)
	  {
	     ((RpcExceptionListener) listeners.elementAt(i)).rpcExceptionPerformed(e);
	  }
       }
   }

  private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
  }
  private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
    ois.defaultReadObject();
  }



}